package com.zmn.oms.zmn.business.impl.tmall;

import com.zmn.oms.business.interfaces.mq.MqProviderService;
import com.zmn.oms.services.interfaces.datasync.ElasticSearchDataSyncService;
import org.apache.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.manager.mq.constant.MqTagConsts;
import com.zmn.manager.mq.constant.MqTopicConsts;
import com.zmn.manager.mq.interfaces.ZmnMQSender;
import com.zmn.oms.business.interfaces.log.OrderLogBService;
import com.zmn.oms.business.interfaces.tmall.OrderTmallExtendBService;
import com.zmn.oms.business.interfaces.track.OrderTrackBService;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderLogConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.common.dto.OmsOperator;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.model.dto.order.proxy.*;
import com.zmn.oms.model.dto.tmall.OrderTmallExtendDTO;
import com.zmn.oms.model.dto.track.OrderTrackDTO;
import com.zmn.oms.model.dto.track.OrderTrackDetailDTO;
import com.zmn.oms.model.dto.work.masterwork.MasterTakeDTO;
import com.zmn.oms.model.dto.work.masterwork.MasterVisitDTO;
import com.zmn.oms.model.dto.work.masterwork.ModifyDutyTimeDTO;
import com.zmn.oms.model.dto.work.modify.must.OrderDistributeBackDTO;
import com.zmn.oms.model.entity.log.OrderLog;
import com.zmn.oms.model.entity.order.OrderQuery;
import com.zmn.oms.model.entity.tamllextend.OrderTmallExtend;
import com.zmn.oms.model.entity.track.OrderTrackQuery;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.vo.track.OrderTrackVO;
import com.zmn.oms.services.interfaces.tmallextend.OrderTmallExtendService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.third.base.util.DutyTimeUtil;
import com.zmn.oms.third.taobao.TaobaoTmcConstants;
import com.zmn.oms.zmn.aop.OrderWorkLogUtils;
import com.zmn.oms.zmn.business.interfaces.tmall.TmallOrderBService;
import com.zmn.oms.zmn.business.interfaces.work.OrderWorkDistributeBackBService;
import com.zmn.oms.zmn.business.interfaces.work.ZsOrderWorkBService;
import com.zmn.oms.zmn.business.interfaces.work.masterwork.ZsMasterWorkBService;
//import com.zmn.plat.common.dto.orderconfig.documentarycontent.DocumentaryContentDIO;
//import com.zmn.plat.common.dto.orderconfig.documentarycontent.DocumentaryContentDRO;
//import com.zmn.plat.dubbo.interfaces.orderconfig.documentarycontent.DocumentaryContentListRemoteService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 类描述：订单天猫接口类
 *
 * @author yule
 * @date 2019/10/25 01:53
 */
@Service
public class TmallOrderBServiceImpl implements TmallOrderBService {
    private Logger logger = LoggerFactory.getLogger(TmallOrderBServiceImpl.class);
    //@Reference(version = com.zmn.base.engineer.common.constants.DubboConsts.INTERFACE_VERSION, check = false)
    //private EngineerTouchModifyRemoteService engineerTouchModifyRemoteService;

    @Autowired
    private MqProviderService mqProviderService;
//    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
//    protected DocumentaryContentListRemoteService documentaryContentListRemoteService;

    @Autowired
    private OrderWorkService orderWorkService;
    @Autowired
    private ZsOrderWorkBService zsOrderWorkBService;
    @Autowired
    private OrderLogBService orderLogBService;
    @Autowired
    private ZsMasterWorkBService zsMasterWorkBService;
    @Autowired
    private OrderWorkDistributeBackBService orderWorkDistributeBackBService;
    @Autowired
    private OrderTmallExtendBService orderTmallExtendBService;
    @Autowired
    private OrderTmallExtendService orderTmallExtendService;
    @Autowired
    private OrderTrackBService orderTrackBService;
    @Autowired
    private ElasticSearchDataSyncService elasticSearchDataSyncService;

    /**
     * 修改预约时间
     *
     * @param dutyTimeDTO
     */
    @Override
    public void updateOrderWorkDutyTime(OrderDutyTimeDTO dutyTimeDTO) throws OmsBaseException {

        ModifyDutyTimeDTO modifyDutyTimeDTO = BeanMapper.map(dutyTimeDTO, ModifyDutyTimeDTO.class);
        this.setLogParam(dutyTimeDTO, modifyDutyTimeDTO);
        try {
            //修改预约时间
            zsOrderWorkBService.updateOrderDutyTime(modifyDutyTimeDTO);

            //存储预约时间，及预约次数
            OrderTmallExtend orderTmallExtend = new OrderTmallExtend();
            orderTmallExtend.setOrderId(modifyDutyTimeDTO.getOrderId());
            if (dutyTimeDTO.getDutyTime() != null && Objects.isNull(dutyTimeDTO.getReserveTimeStart())) {
                //用户期望时间格式化存储
                orderTmallExtend.setBuyerExpectDate(dutyTimeDTO.getDutyTime());
            } else {
                //修改预约时间格式化存储
                orderTmallExtend.setDutyTimeStart(dutyTimeDTO.getReserveTimeStart());
                orderTmallExtend.setDutyTimeEnd(dutyTimeDTO.getReserveTimeEnd());
                orderTmallExtend.setDutyTimeUpdateTime(DateUtil.getNow());
            }
            orderTmallExtendService.updateByKey(orderTmallExtend);

        } catch (Exception e) {
            logger.info("勤鸽保存预约时间" + e.getMessage());
            throw new OmsBaseException("勤鸽保存预约时间失败！");
        }
    }

    //1.签到成功日期 < 预约日期&当前签到时间为：20:00以前
    //  自动修改预约时间，修改为当前日期当前时间段
    //  不展示：提前核销提示
    //2.签到成功日期 < 预约日期&当前签到时间为：20:00以后
    //  不自动修预约时间
    //  仅提示：提前核销提示
    @Override
    public void signIn(SignInDTO signInDTO) throws Exception {
        OrderTmallExtendDTO orderTmallExtendDTO = BeanMapper.map(signInDTO, OrderTmallExtendDTO.class);
        this.setLogParam(signInDTO, orderTmallExtendDTO);
        OrderWork dbOrderWork = orderWorkService.findOrderWorkByKey(orderTmallExtendDTO.getOrderId(), orderTmallExtendDTO.getWorkId());
        if (dbOrderWork == null) {
            throw new OmsBaseException("无效的工单");
        }
        boolean isVisitInAdvance = false; // 提前上门
        boolean isDutyTimeUpdatable = false; // 是否可修改预约时间 (天猫不允许将预约时间修改为超过晚上八点以后)
        if (Objects.nonNull(dbOrderWork.getDutyTime())) {
            //签到时间
            Date signInTime = DateUtil.dateFormatToDate(DateUtil.getNow(), DateUtil.FORMAT_DATE);
            //预约时间
            Date dutyTime = DateUtil.dateFormatToDate(dbOrderWork.getDutyTime(), DateUtil.FORMAT_DATE);
            //签到时间小于预约时间
            isVisitInAdvance = signInTime.before(dutyTime);
            //签到时间小于晚8点
            isDutyTimeUpdatable = DateUtil.getNow().before(DateUtil.parse(DateUtil.toString(signInTime, "yyyy-MM-dd 20:00:00")));
            //显示提前上门标识
            if (isVisitInAdvance && !isDutyTimeUpdatable) {
                orderTmallExtendDTO.setVisitEarlyFlag(GlobalConsts.YES);
            }
        }
        //保存签到信息
        orderTmallExtendBService.updateSignIn(orderTmallExtendDTO);

        //自动修改预约时间
        if (isVisitInAdvance && isDutyTimeUpdatable) {
            Date newDutyTime = DutyTimeUtil.round(DateUtil.getNow(), DateUtil.UNIT_MINUTE);
            ModifyDutyTimeDTO modifyDutyTimeDTO = BeanMapper.map(signInDTO, ModifyDutyTimeDTO.class);
            modifyDutyTimeDTO.setDutyTime(newDutyTime);
            //修改预约时间
            zsOrderWorkBService.updateOrderDutyTime(modifyDutyTimeDTO);
        }

        // 签到后将订单置为已上门
        try {
            MasterVisitDTO masterVisitDTO = new MasterVisitDTO();
            masterVisitDTO.setOrderId(dbOrderWork.getOrderId());
            masterVisitDTO.setWorkId(dbOrderWork.getWorkId());
            masterVisitDTO.setMasterId(dbOrderWork.getMasterId());
            masterVisitDTO.setTmallFlag(GlobalConsts.YES);
            masterVisitDTO.setOperatorLogRemark("收到勤鸽APP签到通知");
            zsMasterWorkBService.updateMasterVisit(masterVisitDTO);
        } catch (OmsBaseException e) {
            logger.error(String.format("【%s】收到勤鸽APP签到通知，更新订单状态为【已上门】时错误：%s",
                    TaobaoTmcConstants.NAME_TMALL_QG, e.getMessage()), e);
        }
    }

    @Override
    public void updateMasterTake(OrderMasterTakeDTO orderMasterTakeDTO) throws OmsBaseException {
        MasterTakeDTO masterTakeDTO = BeanMapper.map(orderMasterTakeDTO, MasterTakeDTO.class);
        this.setLogParam(orderMasterTakeDTO, masterTakeDTO);
        try {
            //勤鸽工程师接单
            zsMasterWorkBService.updateMasterTake(masterTakeDTO);
        } catch (Exception e) {
            logger.info("勤鸽工人接单" + e.getMessage());
            throw new OmsBaseException("勤鸽工人接单失败！");
        }
    }

    @Override
    public void updateDistributeBack(DistributeBackDTO distributeBackDTO) throws OmsBaseException {
        OrderDistributeBackDTO orderDistributeBackDTO = BeanMapper.map(distributeBackDTO, OrderDistributeBackDTO.class);
        orderDistributeBackDTO.setStatus(OrderStatusConsts.WORK_STATUS_ASSIGN);
        orderDistributeBackDTO.setResultStatus(OrderStatusConsts.WORK_RESULT_DOING);
        orderDistributeBackDTO.setOperatorId((long) GlobalConsts.OPERATE_USER_TYPE_SYSTEM);
        orderDistributeBackDTO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_SYSTEM);
        orderDistributeBackDTO.setOperator(GlobalConsts.getOperatorTypeName(GlobalConsts.OPERATE_USER_TYPE_SYSTEM));
        this.setLogParam(distributeBackDTO, orderDistributeBackDTO);
        // 人工放弃
        orderWorkDistributeBackBService.saveDistributeBack(orderDistributeBackDTO);
    }

    @Override
    public void updateVerificationStatus(SignInDTO signInDTO) throws Exception {
        Long orderId = signInDTO.getOrderId();
        // 需要单独触发ES订单同步（ES同步核销时间）
        boolean needTriggerSyncEsOrderWorkAdditionlly = true;

        //核销工单
        OrderTmallExtendDTO signIn = BeanMapper.map(signInDTO, OrderTmallExtendDTO.class);
        this.setLogParam(signInDTO, signIn);
        orderTmallExtendBService.updateVerificationStatus(signIn);

        // 工单为已派单和已领单状态时，自动变更为已上门状态
        OrderWork dbOrderWork = orderWorkService.findOrderWorkByKey(orderId, signInDTO.getWorkId());
        if (Objects.equals(dbOrderWork.getStatus(), OrderStatusConsts.WORK_STATUS_TAKE)
                || Objects.equals(dbOrderWork.getStatus(), OrderStatusConsts.WORK_STATUS_DISTRIBUTE)) {
            //设置工单状态为已上门状态
            MasterVisitDTO masterVisitDTO = BeanMapper.map(signInDTO, MasterVisitDTO.class);
            masterVisitDTO.setMasterId(dbOrderWork.getMasterId());
            masterVisitDTO.setTmallFlag(GlobalConsts.YES);
            zsMasterWorkBService.updateMasterVisit(masterVisitDTO);

            // 修改订单状态会触发ES数据同步，无需再额外单独触发
            needTriggerSyncEsOrderWorkAdditionlly = false;

            if (!NumberUtil.isNullOrZero(dbOrderWork.getMasterId())) {
                // 刷新工程师工单列表版本号
                //engineerTouchModifyRemoteService.saveEngineerWorkVersion(dbOrderWork.getMasterId(), null);
                mqProviderService.sendEngineerWorkVersion(dbOrderWork.getMasterId(), null);
            }
        }

        // 触发ES订单同步（ES同步核销时间）
        if (needTriggerSyncEsOrderWorkAdditionlly) {
            String key = StringUtil.getRandomsString(32);
            String orderIds = JSON.toJSONString(Arrays.asList(orderId));
            elasticSearchDataSyncService.syncWorkIndex(orderId);
        }
    }

    @Override
    public void orderHangUp(OrderHangUpDTO hangUpDTO) throws Exception {
        OrderLogDTO orderLogDTO = BeanMapper.map(hangUpDTO, OrderLogDTO.class);
        orderLogDTO.setType(OrderLogConsts.ORDER_LOG_TYPE_ORDER_HANG_UP);
        orderLogDTO.setOperatorId(hangUpDTO.getChannelId() == null ? (long) OrderConsts.CHANNEL_ID_TMALL_WYG :
                (long) hangUpDTO.getChannelId());
        orderLogDTO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_CHANNEL);
        orderLogDTO.setOperator(hangUpDTO.getMasterName());
        //保存挂起日志
        this.saveOrderLog(hangUpDTO.getOrderId(), orderLogDTO);

        //保存挂起时间
        OrderTmallExtend orderTmallExtend = new OrderTmallExtend();
        orderTmallExtend.setOrderId(hangUpDTO.getOrderId());
        if (Objects.equals(GlobalConsts.YES, hangUpDTO.getHangUpStatus())) {
            orderTmallExtend.setHangUpTime(DateUtil.getNow());
        } else {
            orderTmallExtend.setHangUpTimeUncertain(DateUtil.getNow());
            orderTmallExtend.setNextContactTime(hangUpDTO.getNextContactTime());
        }
        orderTmallExtendService.updateByKey(orderTmallExtend);
    }

    @Override
    public void orderReserveFailed(OrderReserveFailedDTO reserveFailedDTO) throws Exception {
        OrderTmallExtendDTO orderTmallExtendDTO = BeanMapper.map(reserveFailedDTO, OrderTmallExtendDTO.class);
        this.setLogParam(reserveFailedDTO, orderTmallExtendDTO);
        //保存预约失败时间
        OrderTmallExtend orderTmallExtend = new OrderTmallExtend();
        orderTmallExtend.setOrderId(reserveFailedDTO.getOrderId());
        orderTmallExtend.setNextContactTime(reserveFailedDTO.getNextContactTime());
        orderTmallExtend.setDutyTimeFail(DateUtil.getNow());
        orderTmallExtendService.updateByKey(orderTmallExtend);

        //保存下次联系时间至工单
        ModifyDutyTimeDTO modifyDutyTimeDTO = BeanMapper.map(reserveFailedDTO, ModifyDutyTimeDTO.class);
        //修改预约时间
        zsOrderWorkBService.updateOrderDutyTime(modifyDutyTimeDTO);
    }

    @Override
    public void updateExpectDate(OrderDutyTimeDTO orderDutyTimeDTO) throws Exception {
        OrderLogDTO orderLogDTO = BeanMapper.map(orderDutyTimeDTO, OrderLogDTO.class);
        orderLogDTO.setType(OrderLogConsts.ORDER_LOG_TYPE_MODIFY_DUTY_TIME);
        orderLogDTO.setOperatorId(orderDutyTimeDTO.getChannelId() == null ? (long) OrderConsts.CHANNEL_ID_TMALL_WYG :
                (long) orderDutyTimeDTO.getChannelId());
        orderLogDTO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_CHANNEL);
        orderLogDTO.setOperator("系统");
        //保存修改用户期望时间日志
        this.saveOrderLog(orderDutyTimeDTO.getOrderId(), orderLogDTO);

        //发起跟单
        this.tmallAutoOrderTrack(orderDutyTimeDTO);
    }

    /**
     * 申请改约自动跟单
     *
     * @param orderDutyTimeDTO
     */
    private void tmallAutoOrderTrack(OrderDutyTimeDTO orderDutyTimeDTO) throws Exception {
        //查询是否存在天猫申请改约跟单 && 跟单未完成
        OrderTrackQuery query = new OrderTrackQuery();
        query.setOrderId(orderDutyTimeDTO.getOrderId());
        query.setWorkId(orderDutyTimeDTO.getWorkId());
        query.setMapId(OrderConsts.ORDER_TRACT_TMALL_TYPE_ID);
        query.setComplete(GlobalConsts.NO);
        Integer orderTrackCount = orderTrackBService.countByQuery(query);
        logger.info("#api#orderTrackCount 查询1041跟单是否完成：【{}】", JSON.toJSONString(orderTrackCount));
        // 有进行中的跟单则不创建跟单
        if (orderTrackCount != null && orderTrackCount > 0) {
            return;
        }

        //查询指定的跟单信息
        /*List<OrderTrackVO> trackTypeList = Lists.newArrayList();
        DocumentaryContentDIO documentaryContentDIO = new DocumentaryContentDIO();
        documentaryContentDIO.setBizType(orderDutyTimeDTO.getBizType());
        documentaryContentDIO.setStatus(GlobalConsts.YES);
        documentaryContentDIO.setId(OrderConsts.ORDER_TRACT_TMALL_TYPE_ID);
        logger.info("#api#track 查询跟单项目入参：【{}】", JSON.toJSONString(documentaryContentDIO));
        ResponseDTO<List<DocumentaryContentDRO>> responseDTO = documentaryContentListRemoteService.listByQuery(documentaryContentDIO);
        logger.info("#api#track 查询跟单项目出参：【{}】", JSON.toJSONString(responseDTO));
        boolean isSuccess = responseDTO.isSuccess();
        if (isSuccess && !CollectionUtils.isEmpty(responseDTO.getData())) {
            responseDTO.getData().forEach(e -> {
                //int level = Optional.ofNullable(e.getDepartmentPriority()).orElse(e.getServiceProviderDocumentaryPriority());
                //默认跟单等级为一级
                OrderTrackVO orderTrackVO = OrderTrackVO.builder().mapId(e.getId()).mapName(e.getContent()).level(OrderConsts.ORDER_TRACT_OTHER_TYPE_LEVEL).build();
                trackTypeList.add(orderTrackVO);
            });
        }

        if (CollectionUtils.isEmpty(trackTypeList)) {
            logger.info("#api#trackTypeList 查询跟单项为空，不处理--------");
            return;
        }

        //保存跟单信息
        OrderTrackDTO orderTrackDTO = new OrderTrackDTO();
        orderTrackDTO.setComplete(GlobalConsts.NO);
        orderTrackDTO.setOrderId(orderDutyTimeDTO.getOrderId());
        orderTrackDTO.setWorkId(orderDutyTimeDTO.getWorkId());
        orderTrackDTO.setOperator("系统");
        orderTrackDTO.setOperatorId((long) OrderConsts.CHANNEL_ID_TMALL_WYG );
        orderTrackDTO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_CHANNEL);

        List<OrderTrackDetailDTO> detailDTOList = new ArrayList<>(trackTypeList.size());
        orderTrackDTO.setDetailDTOList(detailDTOList);

        trackTypeList.forEach(workTrackDTO -> {
            OrderTrackDetailDTO orderTrackDetailDTO = new OrderTrackDetailDTO();
            orderTrackDetailDTO.setMapId(workTrackDTO.getMapId());
            orderTrackDetailDTO.setMapName(workTrackDTO.getMapName());
            orderTrackDetailDTO.setRemark(workTrackDTO.getRemark());
            orderTrackDetailDTO.setLevel(workTrackDTO.getLevel());
            detailDTOList.add(orderTrackDetailDTO);
        });
        //保存
        orderTrackBService.updateTrack(orderTrackDTO);*/
    }

    /**
     * 添加日志
     *
     * @param orderId
     * @param orderLogDTO
     */
    private void saveOrderLog(Long orderId, OrderLogDTO orderLogDTO) {
        if (orderLogDTO.getType() == null) {
            orderLogDTO.setType(OrderLogConsts.ORDER_LOG_TYPE_CHANNEL_REMARK);
        }
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);
        OrderLog orderLog = new OrderLog();
        orderLog.setOrderId(orderId);
        orderLog.setWorkId(orderId);
        orderLog.setType(orderLogDTO.getType());
        orderLog.setTypeName(OrderLogConsts.getOrderLogTypeName(orderLogDTO.getType()));
        orderLog.setBeforeStatus(orderWork.getStatus());
        orderLog.setBeforeStatusName(OrderStatusConsts.getWorkStatusName(orderWork.getStatus()));
        orderLog.setBeforeResultStatus(orderWork.getResultStatus());
        orderLog.setBeforeResultStatusName(OrderStatusConsts.getWorkResultStatusName(orderWork.getResultStatus()));
        orderLog.setAfterStatus(orderWork.getStatus());
        orderLog.setAfterStatusName(OrderStatusConsts.getWorkStatusName(orderWork.getStatus()));
        orderLog.setAfterResultStatus(orderWork.getResultStatus());
        orderLog.setAfterResultStatusName(OrderStatusConsts.getWorkResultStatusName(orderWork.getResultStatus()));
        OrderWorkLogUtils.processOrderLogOperater(orderLog, orderLogDTO);

        StringBuilder sb = new StringBuilder();
        if (StringUtils.isNotBlank(orderLogDTO.getOperatorRemark())) {
            sb.append(orderLogDTO.getOperatorRemark());
        }

        if (StringUtils.isNotBlank(orderLogDTO.getOperatorLogRemark())) {
            sb.append(orderLogDTO.getOperatorLogRemark());
        }

        orderLog.setContent(sb.toString());
        orderLogBService.save(orderLog);
    }

    // 设置日志参数
    private void setLogParam(OrderQuery orderDto, OmsOperator dto) {
        // 处理操作人
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderDto.getOrderId(), orderDto.getWorkId());
        dto.setOperatorId(dto.getOperatorId() == null ? (long) orderWork.getChannelId() : dto.getOperatorId());
        dto.setOperatorType(dto.getOperatorType() == null ? GlobalConsts.OPERATE_USER_TYPE_CHANNEL : dto.getOperatorType());
        dto.setPlat(orderWork.getPlat());
        dto.setOperator(dto.getOperator() != null ? dto.getOperator() : (StringUtil.isBlank(orderDto.getMasterName()) ? "系统" : orderDto.getMasterName()));
    }
}
